package com.zdkj.subway.stm.controller;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdkj.admin.api.entity.SysDictItem;
import com.zdkj.common.core.constant.CommonConstants;
import com.zdkj.common.core.util.R;
import com.zdkj.common.log.annotation.SysLog;
import com.zdkj.common.security.service.PigxUser;
import com.zdkj.common.security.util.SecurityUtils;
import com.zdkj.subway.stm.constant.StmConstans;
import com.zdkj.subway.stm.dto.in.SwStTicketCheckCheckDTO;
import com.zdkj.subway.stm.dto.in.SwStTicketCheckDTO;
import com.zdkj.subway.stm.entity.SwStTicketCheck;
import com.zdkj.subway.stm.fegin.SystemUserService;
import com.zdkj.subway.stm.mapper.SwStStockMapper;
import com.zdkj.subway.stm.mapper.SwStTicketCheckMapper;
import com.zdkj.subway.stm.service.SwStStockService;
import com.zdkj.subway.stm.service.SwStTicketCheckService;
import com.zdkj.subway.stm.util.DateUtilStm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 车票盘点数据
 *
 * @author songtuo
 * @date 2020-07-11 22:08:18
 */
@RestController
@AllArgsConstructor
@RequestMapping("/swstticketcheck")
@Api(value = "swstticketcheck", tags = "车票盘点数据管理")
@Slf4j
public class SwStTicketCheckController {

    private final SwStTicketCheckService swStTicketCheckService;

    private final SystemUserService systemUserService;
    @Resource
    SwStTicketCheckMapper swStTicketCheckMapper;

    @Resource
    SwStStockMapper swStStockMapper;


    @Autowired
    SwStStockService swStStockService;


    /**
     * 分页查询
     *
     * @param page            分页对象
     * @param swStTicketCheck 车票盘点数据
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    public R getSwStTicketCheckPage(Page page, SwStTicketCheck swStTicketCheck) {
        QueryWrapper<SwStTicketCheck> queryWrapper = Wrappers.query(swStTicketCheck);
        List<String> dateCondition = swStTicketCheck.getDates1();
        queryWrapper.orderByDesc("CHECK_TIME");
        if (!SecurityUtils.getUser().getBelongToLine()) {
            queryWrapper.lambda().eq(SwStTicketCheck::getLineCode, SecurityUtils.getUser().getLineCode());
            queryWrapper.lambda().eq(SwStTicketCheck::getStationCode, SecurityUtils.getUser().getStationCode());
            if (ObjectUtil.isNotEmpty(dateCondition)) {
                queryWrapper.between("check_time", dateCondition.get(0), dateCondition.get(1));
            }
            return R.ok(swStTicketCheckService.page(page, queryWrapper));
        }
        if (ObjectUtil.isNotEmpty(dateCondition)) {
            queryWrapper.between("check_time", dateCondition.get(0), dateCondition.get(1));
        }
        return R.ok(swStTicketCheckService.page(page, queryWrapper));
    }

    /**
     * 分页查询
     * @param page 分页对象
     * @param statisticsDate 其他票款管理
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/query" )
    public R getSwStOtherFarePage(Page page, String lineCode, String stationCode, String statisticsDate) {
        return R.ok(swStStockMapper.getSwStStockPage(page,lineCode,stationCode,statisticsDate));
    }

    /**
     * 通过id查询车票盘点数据
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    public R getById(@PathVariable("id") Integer id) {
        return R.ok(swStTicketCheckService.getById(id));
    }

    /**
     * 新增车票盘点数据
     *
     * @param swStTicketCheckDTO 车票盘点数据
     * @return R
     */
    @ApiOperation(value = "新增车票盘点数据", notes = "新增车票盘点数据")
    @SysLog("新增车票盘点数据")
    @PostMapping
    @PreAuthorize("@pms.hasPermission('swstticketcheck_add')")
    public R save(@RequestBody SwStTicketCheckDTO swStTicketCheckDTO) {
        SwStTicketCheck ticketCheck = swStTicketCheckDTO.getTicketCheck();
        //重新设置盘点时间
        LocalDateTime checkTime = ticketCheck.getCheckTime();
        String timeToString = DateUtilStm.LocalDateTimeToString(checkTime);
        //盘点日期从字典获取
        String checkDay = swStStockService.getCheckDay();
        String newDate = timeToString.substring(0, 8) + checkDay;
        R r = this.getTicketCheck(newDate);
        Object data = r.getData();
        if(data != null){
            return R.failed("所选日期的盘点数据已录入，请勿重复录入！");
        }
        String newDateTime =  newDate + timeToString.substring(10,19);
        LocalDateTime localDateTime = DateUtilStm.LocalDateTimeToString(newDateTime);
        ticketCheck.setCheckTime(localDateTime);
        return R.ok(swStTicketCheckService.saveSwStTicketCheck(swStTicketCheckDTO));
    }

    /**
     * 修改车票盘点数据
     *
     * @param swStTicketCheckDTO 车票盘点数据
     * @return R
     */
    @ApiOperation(value = "修改车票盘点数据", notes = "修改车票盘点数据")
    @SysLog("修改车票盘点数据")
    @PutMapping
    @PreAuthorize("@pms.hasPermission('swstticketcheck_edit')")
    public R updateById(@RequestBody SwStTicketCheckDTO swStTicketCheckDTO) {
        SwStTicketCheck ticketCheck = swStTicketCheckDTO.getTicketCheck();
        //重新设置盘点时间
        LocalDateTime checkTime = ticketCheck.getCheckTime();
        String timeToString = DateUtilStm.LocalDateTimeToString(checkTime);
        //盘点日期从字典获取
        String checkDay = swStStockService.getCheckDay();
        String newDate = timeToString.substring(0, 8) + checkDay;
        String newDateTime =  newDate + timeToString.substring(10,19);
        LocalDateTime localDateTime = DateUtilStm.LocalDateTimeToString(newDateTime);

        SwStTicketCheck byId = swStTicketCheckService.getById(ticketCheck.getId());
        //编辑校验时，过滤掉自身
        if(ObjectUtil.isNotEmpty(byId)){
            LocalDate oldDate = byId.getCheckTime().toLocalDate();
            LocalDate date = localDateTime.toLocalDate();
            if(!oldDate.isEqual(date)){
                R r = this.getTicketCheck(newDate);
                Object data = r.getData();
                if(data != null){
                    return R.failed("所选日期的盘点数据已录入，请勿重复录入！");
                }
            }
        }
        ticketCheck.setCheckTime(localDateTime);
        return R.ok(swStTicketCheckService.updateSwStTicketCheck(swStTicketCheckDTO));
    }

    /**
     * 通过id删除车票盘点数据
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除车票盘点数据", notes = "通过id删除车票盘点数据")
    @SysLog("通过id删除车票盘点数据")
    @DeleteMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('swstticketcheck_del')")
    public R removeById(@PathVariable Integer id) {
        return R.ok(swStTicketCheckService.deleteCascadeById(id));
    }


    /**
     * 查询日结账单详情
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询车票盘点数据详情", notes = "通过id查询")
    @GetMapping("/details/{id}")
    public R getSwStTicketCheck(@PathVariable("id") Integer id) {
        return R.ok(swStTicketCheckService.queryDetailsByid(id));
    }

    /**
     * 通过日期查询当月车票盘点数据
     *
     * @param checkTime
     * @return R
     */
    @ApiOperation(value = "通过日期查询当月车票盘点数据", notes = "通过日期查询")
    @GetMapping("/getTicketCheck")
    public R getTicketCheck(String checkTime) {
        SwStTicketCheck swStTicketCheck = new SwStTicketCheck();
        PigxUser user = SecurityUtils.getUser();
        LambdaQueryWrapper<SwStTicketCheck> queryWrapper = Wrappers.query(swStTicketCheck).lambda();
        queryWrapper.eq(SwStTicketCheck::getLineCode,user.getLineCode());
        queryWrapper.eq(SwStTicketCheck::getStationCode,user.getStationCode());
        queryWrapper.likeRight(SwStTicketCheck::getCheckTime,checkTime);
        queryWrapper.in(SwStTicketCheck::getStatus,0,1,2,4);
        return R.ok(swStTicketCheckService.getMap(queryWrapper));
    }
    /**
     * 通过日期查询当月已提交车票盘点数据
     *
     * @param checkTime
     * @return R
     */
    @ApiOperation(value = "通过日期查询当月已提交车票盘点数据", notes = "通过日期查询")
    @GetMapping("/getTicketCheckOfSubmit")
    public R getTicketCheckOfSubmit(String checkTime) {
        PigxUser user = SecurityUtils.getUser();
        SwStTicketCheck swStTicketCheck = new SwStTicketCheck();
        LambdaQueryWrapper<SwStTicketCheck> queryWrapper = Wrappers.query(swStTicketCheck).lambda();
        queryWrapper.eq(SwStTicketCheck::getLineCode,user.getLineCode());
        queryWrapper.eq(SwStTicketCheck::getStationCode,user.getStationCode());
        queryWrapper.likeRight(SwStTicketCheck::getCheckTime,checkTime);
        queryWrapper.eq(SwStTicketCheck::getStatus,1);
        return R.ok(swStTicketCheckService.getMap(queryWrapper));
    }

    /**
     * 批量删除子表
     *
     * @param idList
     * @return
     */
    @SysLog("通过id批量删除车票盘点数据")
    @DeleteMapping("/batchCascadeDel")
    @PreAuthorize("@pms.hasPermission('swstticketcheck_batch_del')")
    @Transactional
    @ApiOperation(value = "通过id删除车票盘点数据", notes = "通过id删除车票盘点数据")
    public R batchRemoveById(@RequestBody List<Integer> idList) {
        List<SwStTicketCheck> list = swStTicketCheckService.list(new QueryWrapper<SwStTicketCheck>().lambda().in(SwStTicketCheck::getId, idList));
        //未提交的数据才能删除其他的不能删除
        List<Integer> deleteIds = list.stream().filter(x -> x.getStatus().equals(CommonConstants.UN_SUBMIT)).map(x -> x.getId()).collect(Collectors.toList());
        deleteIds.forEach(swStTicketCheckService::deleteCascadeById);
        return R.ok();
    }

    @ApiOperation(value = "导出车票盘点数据", notes = "导出车票盘点数据")
    @GetMapping("/export")
    public void export(@RequestParam(value = "ids") List<Integer> ids, HttpServletResponse response) {
        List<SwStTicketCheck> records = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(ids)){
            records =swStTicketCheckMapper.selectBatchIds(ids).stream().sorted(Comparator.comparing(SwStTicketCheck::getCheckTime).reversed()).collect(Collectors.toList());
        }else{
            QueryWrapper<SwStTicketCheck> wrapper = new QueryWrapper<>();
            wrapper.lambda().eq(SwStTicketCheck::getLineCode,SecurityUtils.getUser().getLineCode())
                    .eq(SwStTicketCheck::getStationCode,SecurityUtils.getUser().getStationCode())
                    .eq(SwStTicketCheck::getDelFlag,"0")
                    .orderByDesc(SwStTicketCheck::getCheckTime);
            records = swStTicketCheckService.list(wrapper);
        }
        try {
            R<List<SysDictItem>> inputDataStatus = systemUserService.getDictByType(StmConstans.STM_TICKE_CHECK_STATUS);
            List<SysDictItem> dictData = inputDataStatus.getData();
            for (SwStTicketCheck record : records) {
                Map<String, String> map = dictData.stream().collect(Collectors.toMap(SysDictItem::getValue, SysDictItem::getLabel));
                record.setStatus(map.get(record.getStatus()));
            }
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("车票盘点数据", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + System.currentTimeMillis() + ".xlsx");
            EasyExcel.write(response.getOutputStream(), SwStTicketCheck.class).
                    sheet("车票盘点数据").doWrite(records);
        } catch (IOException e) {
            log.error("导出车票盘点数据失败");
        }
    }

    /**
     * 车票盘点数据审核
     */
    @ApiOperation(value = "车票盘点数据审核", notes = "车票盘点数据审核")
    @PutMapping("/check/status")
    @PreAuthorize("@pms.hasPermission('swstticketcheck_check')")
    public R checkStatus(@RequestBody SwStTicketCheckCheckDTO dto) {
        return R.ok(swStTicketCheckService.checkStatus(dto));
    }

    /**
     * 车票盘点数据批量提交
     */
    @ApiOperation(value = "车票盘点数据批量提交", notes = "车票盘点数据批量提交")
    @PutMapping("/modify/approval/status")
    @PreAuthorize("@pms.hasPermission('swstticketcheck_approval_status')")
    public R updateApprovalStatus(@RequestParam("ids") List<Integer> ids, @RequestParam("status") String status) {
        return R.ok(swStTicketCheckService.updateApprovalStatus(ids, status));
    }

}
